﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Fis.Win.Utils;
using Agile.Engine.Data;
using System.Collections;
using Agile.Engine;
using Agile.Engine.Utils;

namespace Fis.Win.Forms
{
    public partial class PreRestReportForm : RestReportForm
    {
        public override void InitializeViewUI()
        {
            Text = "试算平衡表";
            base.InitializeViewUI();
        }

        public override void InitializeBinding()
        {
            var data = CreatePreRestData();
            if (data != null)
            {
                data.DefaultView.RowFilter = "NOT( FDEBITAMOUNTBQ = FCREDITAMOUNTBQ AND (FCREDITAMOUNTBQ = 0) )";
                theGridControl.DataSource = data;
                data.DefaultView.Sort = "FRANGE,FCODE";
            }
        }

        protected override DataTable GetRestData()
        {
            var sql = @"SELECT FACCCODE,'{0}' FRANGE,sum(FDEBITAMOUNTBQ) SUMJ,sum(FCREDITAMOUNTBQ) SUMD,sum(FQUANTITYDEBITBQ) SUMQJ,sum(FQUANTITYCREDITBQ) SUMQD
                        FROM TREST
                        group by FACCCODE";
            return Agile.Engine.Data.DataContext.Get("CacheDataContext").DefaultModel.QueryTable(CommandType.Text, "RestData", string.Format(sql, AppSession.Range));
        }

        DataTable CreatePreRestData()
        {
            Hashtable model = new Hashtable();
            var dataContext = Agile.Engine.Data.DataContext.Get("CacheDataContext");

            var Sql = (string)null;
            var Year = int.Parse(AppSession.Year);
            var Range = int.Parse(AppSession.Range);
            var StarTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range));
            var EndTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range)).AddMonths(1);
            Sql = string.Format("select * from TBILLMASTER where FENTERDATE>='{0}' and FENTERDATE<'{1}'", StarTime, EndTime);
            model["BillMasterTB"] = dataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, "BillMasterTB", Sql);
            var filter0 = string.Format("and FENTERDATE>='{0}' and FENTERDATE<'{1}'", StarTime, EndTime);
            Sql = ObjectContext.GetResource("SqlResource").Format("billQuery", filter0
                    , string.IsNullOrEmpty(null) ? string.Empty : ObjectContext.GetResource("SqlResource").Format("billSubQuery", null));
            model["BillDetailTB"] = dataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, "BillDetailTB", Sql);
            model["AccountTB"] = dataContext.DefaultModel.QueryTable("TACCOUNT");
            var LowerAccountTB = CacheContext.LowerAccountCache();
            model["LowerAccountSID"] = string.Format("'{0}'", string.Join("','", (from a in LowerAccountTB.Select("") select a["SID"].ToString()).ToArray()));
            Sql = ObjectContext.GetResource("SqlResource").Format("TransferProfitAccount", string.Format("FENTERDATE>='{0}' and FENTERDATE<'{1}'", StarTime, EndTime));
            var TransferProfitAccountTB = dataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, "LowerAccountSID", Sql);
            model["TransferProfitAccountSID"] = string.Format("'{0}'", string.Join("','", (from a in TransferProfitAccountTB.Select("") select a["SID"].ToString()).ToArray()));
            Sql = string.Format("select * from TREST where FRANGE={0}", Range - 1);
            model["RestTB"] = dataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, "RestTB", Sql);

            var restDB = RateBuild(model).Select(string.Format("FRANGE= '{0}'", Range));
            if (restDB.Length > 0)
            {
                var data = restDB.CopyToDataTable();
                if (NulltoDecimal(data.Compute("sum(FDEBITAMOUNTQM)", string.Format("FACCCODE in ({0})", model["LowerAccountSID"])).ToString()) !=
                      NulltoDecimal(data.Compute("sum(FCREDITAMOUNTQM)", string.Format("FACCCODE in ({0})", model["LowerAccountSID"])).ToString()))
                {
                    Message = "科目余额借贷不平，请调整后重新结账！";

                }

                if (!string.IsNullOrEmpty(AccFilter))
                {
                    var filter = data.Select(string.Format("FACCCODE='{0}'", AccFilter));
                    if (filter.Length > 0)
                        data = filter.CopyToDataTable();
                    else
                        return null;
                }

                var rest = GetRestData();
                rest.PrimaryKey = new DataColumn[] { rest.Columns["FRANGE"], rest.Columns["FACCCODE"] };
                data.PrimaryKey = new DataColumn[] { data.Columns["FRANGE"], data.Columns["FACCCODE"] };

                data.Merge(rest, false, MissingSchemaAction.Add);

                return data;
            }
            return null;
        }

        DataTable RateBuild(Hashtable args)
        {
            var AccountTB = args["AccountTB"] as DataTable;
            var RestTB = args["RestTB"] as DataTable;
            var TempBillTB = args["BillDetailTB"] as DataTable;
            var Range = AppSession.Range;
            var SID = (string)null;
            var FCode = (string)null;


            //添加科目信息
            if (!RestTB.Columns.Contains("FCODE"))
                RestTB.Columns.Add("FCODE");
            if (!RestTB.Columns.Contains("FNAME"))
                RestTB.Columns.Add("FNAME");
            if (!RestTB.Columns.Contains("FUNIT"))
                RestTB.Columns.Add("FUNIT");

            for (int i = 0; i < AccountTB.Rows.Count; i = i + 1)
            {
                var RestRow = RestTB.NewRow();
                SID = AccountTB.Rows[i]["SID"].ToString();
                FCode = AccountTB.Rows[i]["FCODE"].ToString();
                FCode = string.Format("'{0}'", string.Join("','",
                        (from a in AccountTB.Select(string.Format("FCODE like '{0}%'", FCode)) select a["SID"].ToString()).ToArray()));
                RestRow["SID"] = "";
                RestRow["FACCCODE"] = SID;

                RestRow["FCODE"] = AccountTB.Rows[i]["FCODE"];
                RestRow["FNAME"] = AccountTB.Rows[i]["FNAME"];
                RestRow["FUNIT"] = AccountTB.Rows[i]["FUNIT"];

                //初始化起初余额
                RestRow["FDEBITAMOUNTQC"] = decimal.Parse("0.000000");
                RestRow["FCREDITAMOUNTQC"] = decimal.Parse("0.000000");
                RestRow["FCURRENCYDEBITQC"] = decimal.Parse("0.000000");
                RestRow["FCURRENCYCREDITQC"] = decimal.Parse("0.000000");
                RestRow["FQUANTITYDEBITQC"] = decimal.Parse("0.000000");
                RestRow["FQUANTITYCREDITQC"] = decimal.Parse("0.000000");
                //初始化本期余额
                RestRow["FDEBITAMOUNTBQ"] = decimal.Parse("0.000000");
                RestRow["FCREDITAMOUNTBQ"] = decimal.Parse("0.000000");
                RestRow["FCURRENCYDEBITBQ"] = decimal.Parse("0.000000");
                RestRow["FCURRENCYCREDITBQ"] = decimal.Parse("0.000000");
                RestRow["FQUANTITYDEBITBQ"] = decimal.Parse("0.000000");
                RestRow["FQUANTITYCREDITBQ"] = decimal.Parse("0.000000");
                if (Range != "0")
                {
                    RestRow["FDEBITAMOUNTQC"] = NulltoDecimal(RestTB.Compute("sum(FDEBITAMOUNTQM)", string.Format("FACCCODE='{0}' and FRANGE={1}", SID, int.Parse(Range) - 1)).ToString());
                    RestRow["FCREDITAMOUNTQC"] = NulltoDecimal(RestTB.Compute("sum(FCREDITAMOUNTQM)", string.Format("FACCCODE='{0}' and FRANGE={1}", SID, int.Parse(Range) - 1)).ToString());
                    RestRow["FCURRENCYDEBITQC"] = NulltoDecimal(RestTB.Compute("sum(FCURRENCYDEBITQM)", string.Format("FACCCODE='{0}' and FRANGE={1}", SID, int.Parse(Range) - 1)).ToString());
                    RestRow["FCURRENCYCREDITQC"] = NulltoDecimal(RestTB.Compute("sum(FCURRENCYCREDITQM)", string.Format("FACCCODE='{0}' and FRANGE={1}", SID, int.Parse(Range) - 1)).ToString());
                    RestRow["FQUANTITYDEBITQC"] = NulltoDecimal(RestTB.Compute("sum(FQUANTITYDEBITQM)", string.Format("FACCCODE='{0}' and FRANGE={1}", SID, int.Parse(Range) - 1)).ToString());
                    RestRow["FQUANTITYCREDITQC"] = NulltoDecimal(RestTB.Compute("sum(FQUANTITYCREDITQM)", string.Format("FACCCODE='{0}' and FRANGE={1}", SID, int.Parse(Range) - 1)).ToString());
                }
                if (TempBillTB != null)
                {
                    RestRow["FDEBITAMOUNTBQ"] = NulltoDecimal(TempBillTB.Compute("sum(FDEBITAMOUNT)", string.Format("FACCOUNTCODE in ({0})", FCode)).ToString());
                    RestRow["FCREDITAMOUNTBQ"] = NulltoDecimal(TempBillTB.Compute("sum(FCREDITAMOUNT)", string.Format("FACCOUNTCODE in ({0})", FCode)).ToString());
                    RestRow["FCURRENCYDEBITBQ"] = NulltoDecimal(TempBillTB.Compute("sum(FCURRENCYDEBIT)", string.Format("FACCOUNTCODE in ({0})", FCode)).ToString());
                    RestRow["FCURRENCYCREDITBQ"] = NulltoDecimal(TempBillTB.Compute("sum(FCURRENCYCREDIT)", string.Format("FACCOUNTCODE in ({0})", FCode)).ToString());
                    RestRow["FQUANTITYDEBITBQ"] = NulltoDecimal(TempBillTB.Compute("sum(FQUANTITYDEBIT)", string.Format("FACCOUNTCODE in ({0})", FCode)).ToString());
                    RestRow["FQUANTITYCREDITBQ"] = NulltoDecimal(TempBillTB.Compute("sum(FQUANTITYCREDIT)", string.Format("FACCOUNTCODE in ({0})", FCode)).ToString());
                }
                RestRow["FDEBITAMOUNTQM"] = decimal.Parse(RestRow["FDEBITAMOUNTQC"].ToString()) + decimal.Parse(RestRow["FDEBITAMOUNTBQ"].ToString());
                RestRow["FCREDITAMOUNTQM"] = decimal.Parse(RestRow["FCREDITAMOUNTQC"].ToString()) + decimal.Parse(RestRow["FCREDITAMOUNTBQ"].ToString());
                RestRow["FCURRENCYDEBITQM"] = decimal.Parse(RestRow["FCURRENCYDEBITQC"].ToString()) + decimal.Parse(RestRow["FCURRENCYDEBITBQ"].ToString());
                RestRow["FCURRENCYCREDITQM"] = decimal.Parse(RestRow["FCURRENCYCREDITQC"].ToString()) + decimal.Parse(RestRow["FCURRENCYCREDITBQ"].ToString());
                RestRow["FQUANTITYDEBITQM"] = decimal.Parse(RestRow["FQUANTITYDEBITQC"].ToString()) + decimal.Parse(RestRow["FQUANTITYDEBITBQ"].ToString());
                RestRow["FQUANTITYCREDITQM"] = decimal.Parse(RestRow["FQUANTITYCREDITQC"].ToString()) + decimal.Parse(RestRow["FQUANTITYCREDITBQ"].ToString());
                RestRow["FRANGE"] = Range;
                RestRow["SINDEXDATE"] = System.DateTime.Now;
                RestRow["SBOOKID"] = "";
                RestTB.Rows.Add(RestRow);
            }
            return RestTB;
        }

        decimal NulltoDecimal(string Key)
        {
            if (StringUtils.IsEmpty(Key))
            {
                return decimal.Parse("0.000000");
            }
            return decimal.Parse(Key);
        }

    }
}
